/******************************************************************************
 *  Compilation:  javac Interval2D.java
 *  Execution:    java Interval2D
 *  Dependencies: StdOut.java Interval1D.java StdDraw.java
 *
 *  2-dimensional interval data type.
 *
 ******************************************************************************/

package hwOne2;

import edu.princeton.cs.algs4.Interval1D;
import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdRandom;

/**
 *  The {@code Interval2D} class represents a closed two-dimensional interval,
 *  which represents all points (x, y) with both {@code xmin <= x <= xmax} and
 *  {@code ymin <= y <= ymax}.
 *  Two-dimensional intervals are immutable: their values cannot be changed
 *  after they are created.
 *  The class {@code Interval2D} includes methods for checking whether
 *  a two-dimensional interval contains a point and determining whether
 *  two two-dimensional intervals intersect.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *  @author Robert Sedgewick
 *  @author Kevin Wayne
 */
public class Interval2D {
    private final edu.princeton.cs.algs4.Interval1D x;
    private final edu.princeton.cs.algs4.Interval1D y;

    /**
     * Initializes a two-dimensional interval.
     * @param x the one-dimensional interval of x-coordinates
     * @param y the one-dimensional interval of y-coordinates
     */
    public Interval2D(edu.princeton.cs.algs4.Interval1D x, edu.princeton.cs.algs4.Interval1D y) {
        this.x = x;
        this.y = y;
    }

    /**
     * Does this two-dimensional interval intersect that two-dimensional interval?
     * @param that the other two-dimensional interval
     * @return true if this two-dimensional interval intersects
     *    that two-dimensional interval; false otherwise
     */
    public boolean intersects(Interval2D that) {
        if (!this.x.intersects(that.x)) return false;
        if (!this.y.intersects(that.y)) return false;
        return true;
    }


//    public boolean contains(edu.princeton.cs.algs4.Point2D p) {
//        return x.contains(p.x())  && y.contains(p.y());
//    }
    public boolean contains(Interval2D other) {
        return this.x.min() <= other.x.min() && this.x.max() >= other.x.max() &&
                this.y.min() <= other.y.min() && this.y.max() >= other.y.max();
    }

    /**
     * Returns the area of this two-dimensional interval.
     * @return the area of this two-dimensional interval
     */
    public double area() {
        return x.length() * y.length();
    }

    /**
     * Returns a string representation of this two-dimensional interval.
     * @return a string representation of this two-dimensional interval
     *    in the form [xmin, xmax] x [ymin, ymax]
     */
    public String toString() {
        return x + " x " + y;
    }

    /**
     * Does this interval equal the other interval?
     * @param other the other interval
     * @return true if this interval equals the other interval; false otherwise
     */
    public boolean equals(Object other) {
        if (other == this) return true;
        if (other == null) return false;
        if (other.getClass() != this.getClass()) return false;
        Interval2D that = (Interval2D) other;
        return this.x.equals(that.x) && this.y.equals(that.y);
    }


    /**
     * Returns an integer hash code for this interval.
     * @return an integer hash code for this interval
     */
    public int hashCode() {
        int hash1 = x.hashCode();
        int hash2 = y.hashCode();
        return 31*hash1 + hash2;
    }

    /**
     * Draws this two-dimensional interval to standard draw.
     */
    public void draw() {
        double xc = (x.min() + x.max()) / 2.0;
        double yc = (y.min() + y.max()) / 2.0;
        StdDraw.rectangle(xc, yc, x.length() / 2.0, y.length() / 2.0);
    }

    public static void main(String[] args) {
        // 从命令行读取参数
        int N = Integer.parseInt(args[0]); // 生成的随机2D间隔数量
        double min = Double.parseDouble(args[1]); // 最小值
        double max = Double.parseDouble(args[2]); // 最大值

        // 检查输入的有效性
        if (min < 0 || max > 1 || min >= max) {
            throw new IllegalArgumentException("min and max must satisfy 0 <= min < max <= 1");
        }

        // 设置绘图窗口
        StdDraw.setXscale(0, 1);
        StdDraw.setYscale(0, 1);
        StdDraw.setPenRadius(0.005);

        // 存储生成的2D间隔
        Interval2D[] intervals = new Interval2D[N];

        // 生成N个随机的2D间隔
        for (int i = 0; i < N; i++) {
            // 随机生成x方向和y方向的1D间隔
            double x1 = StdRandom.uniform(min, max);
            double x2 = StdRandom.uniform(min, max);
            double y1 = StdRandom.uniform(min, max);
            double y2 = StdRandom.uniform(min, max);

            // 确保方向上的区间是从小到大
            double xmin = Math.min(x1, x2);
            double xmax = Math.max(x1, x2);
            double ymin = Math.min(y1, y2);
            double ymax = Math.max(y1, y2);

            // 创建1D间隔
            Interval1D xInterval = new Interval1D(xmin, xmax);
            Interval1D yInterval = new Interval1D(ymin, ymax);

            // 创建2D间隔
            intervals[i] = new Interval2D(xInterval, yInterval);

            // 绘制该2D间隔
            intervals[i].draw();
        }

        // 统计相交的间隔对和包含关系的间隔对的数量
        int intersectCount = 0;
        int containCount = 0;

        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                // 判断是否相交
                if (intervals[i].intersects(intervals[j])) {
                    intersectCount++;
                }

                // 判断是否存在包含关系
                if (intervals[i].contains(intervals[j]) || intervals[i].contains(intervals[j])) {
                    containCount++;
                }
            }
        }

        // 打印结果
        System.out.println("Number of intersecting pairs: " + intersectCount);
        System.out.println("Number of containing pairs: " + containCount);
    }


}

/******************************************************************************
 *  Copyright 2002-2022, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/
